package com.googlecode.framework.web.struts2.interceptor;

import java.text.MessageFormat;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.googlecode.framework.web.user.LoginUserHolder;
import com.googlecode.framework.web.user.UserObject;
import com.opensymphony.xwork2.ActionInvocation;

public class ExceptionLoggingInterceptor extends LoggingInterceptor {

    /**
     * serialVersionUID
     */
    private static final long serialVersionUID = -3198104194320582026L;

    private Logger logger = LoggerFactory.getLogger(getClass());

    /*
     * (non-Javadoc)
     * @see com.opensymphony.xwork2.interceptor.AbstractInterceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
     */
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        try {
            return super.intercept(invocation);
        } catch (Exception e) {
            logError(invocation, e);
            throw e;
        }
    }
    
    /*
     * [Error] [sessionid=][user=admin] Execute xxxxx.
     * <<Http Header>>
     *          Accept  
     * Accept-Encoding  
     * Accept-Language
     *      Connection
     *          Cookie
     *             DNT
     *            Host
     * <<Http Parameter>>
     *           Param1
     *           Param2
     *           Param3
     * <<Http Attribute>>
     *       Attribute1
     *       Attribute2
     *       Attribute3
     * <<Session>> 
     *       sessionid
     *      Attribute1
     *      Attribute2
     *      Attribute3
     * <<Throwable>>
     * 
     * 
     */
    protected void logError(ActionInvocation invocation, Exception e) {
        if (logger.isErrorEnabled()) {
            // request
            HttpServletRequest request = ServletActionContext.getRequest();
            // session
            HttpSession session = request.getSession(false); 
            // user
            UserObject user = LoginUserHolder.getCurrentUser();
            // [Error] [sessionid=][user=admin] Execute xxxxx.
            logger.error(MessageFormat.format("[sessionid={0}][user={1}] Execute {2} {3}.", 
                    session == null ? null : session.getId(),
                    user == null ? null : user.getUsername(), 
                    invocation.getProxy().getNamespace(), 
                    invocation.getProxy().getActionName()), e);
            
            // <<Http Request>>
            print(request);
            // <<Http Session>>
            print(session);
            
        }        
    }
    
    protected void print(HttpServletRequest request) {
        final String CRLF = "\r\n";
        
        StringBuilder sb = new StringBuilder();
        // 请求头信息
        sb.append("<<Http Request Header>>");
        sb.append(CRLF);
        Enumeration<?> names = request.getHeaderNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
//            sb.append(StringUtils.padSpace(name, 20));
            sb.append(name);
            sb.append("  ");
            sb.append(request.getHeader(name));
            sb.append(CRLF);
        }
        
        // 请求参数
        sb.append("<<Http Request Parameter>>");
        sb.append(CRLF);
        Enumeration<?> paramNames = request.getParameterNames();
        while (paramNames.hasMoreElements()) {
            String paramName = (String) paramNames.nextElement();
//            sb.append(StringUtils.padSpace(paramName, 20));
            sb.append(paramName);
            sb.append("  ");
            sb.append(request.getParameterValues(paramName));
            sb.append(CRLF);
        }
        
        // 请求属性
        sb.append("<<Http Request Attribute>>");
        sb.append(CRLF);
        Enumeration<?> attrNames = request.getAttributeNames();
        while (attrNames.hasMoreElements()) {
            String attrName = (String) attrNames.nextElement();
//            sb.append(StringUtils.padSpace(paramName, 20));
            sb.append(attrName);
            sb.append("  ");
            sb.append(request.getAttribute(attrName));
            sb.append(CRLF);
        }
        
        logger.error(sb.toString());
    }
    
    protected void print(HttpSession session) {
        if (session == null) {
            return;
        }
        final String CRLF = "\r\n";
        
        StringBuilder sb = new StringBuilder();
        // 请求头信息
        sb.append("<<Http Session>>");
        sb.append(CRLF);
        Enumeration<?> names = session.getAttributeNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
//            sb.append(StringUtils.padSpace(name, 20));
            sb.append(name);
            sb.append("  ");
            sb.append(session.getAttribute(name));
            sb.append(CRLF);
        }
        
        logger.error(sb.toString());
    }
    
}
